精通 Pandas DataFrame 的创建艺术。本指南涵盖了从字典、列表、NumPy 数组等初始化 DataFrame 的方法,专为全球数据专业人士打造。
Pandas DataFrame 创建:深入探讨数据结构初始化
欢迎来到 Python 数据操作的世界!几乎所有数据分析任务的核心都是 Pandas 库,而其基石便是 DataFrame。可以将 DataFrame 视为一个智能、强大且灵活的电子表格或数据库表的版本,它存在于您的 Python 环境中。它是数据清洗、转换、分析和可视化的主要工具。但在进行任何这些数据魔法之前,您必须首先掌握创建 DataFrame 的艺术。如何初始化这个基本数据结构可以为您的整个分析奠定基础。
这本全面的指南专为全球有抱负和正在实践的数据分析师、科学家和工程师设计。我们将探讨从头开始创建 Pandas DataFrame 最常用和最强大的方法。无论您的数据是以字典、列表、NumPy 数组还是其他格式存在,本文都将为您提供知识和实际示例,让您自信高效地初始化 DataFrame。让我们打下基础。
Pandas DataFrame 究竟是什么?
在开始构建之前,让我们澄清我们正在构建什么。Pandas DataFrame 是一种二维的、大小可变的、并且可能是异构的表格数据结构。让我们对其进行分解:
- 二维: 它有行和列,就像电子表格一样。
- 大小可变: 在 DataFrame 创建后,您可以添加或删除行和列。
- 异构: 列可以具有不同的数据类型。例如,一列可以包含数字(整数或浮点数),另一列可以包含文本(字符串),第三列可以包含日期或布尔值(True/False)。
DataFrame 有三个主要组成部分:
- 数据: 结构中包含的实际值,按行和列组织。
- 索引: 行的标签。如果您不提供索引,Pandas 会创建一个从 0 开始的默认索引。索引提供了一种强大的方式来访问和对齐数据。
- 列: 列的标签。这些对于访问 DataFrame 中的特定数据系列至关重要。
理解这种结构是有效创建和操作 DataFrame 的关键。
基础:导入 Pandas
首先,要使用 Pandas,您必须将该库导入到您的 Python 脚本或 Notebook 中。全球专业人士普遍遵循的约定是使用别名 pd 来导入它。这个简单的别名使您的代码更具可读性和简洁性。
import pandas as pd
import numpy as np # 通常与 Pandas 一起使用,所以我们也会导入它。
通过这一行代码,您就解锁了 Pandas 库的全部力量。现在,让我们进入本指南的核心:创建 DataFrame。
核心创建方法:从简单到复杂
pd.DataFrame() 构造函数功能极其强大。它可以接受许多不同类型的输入。现在我们将探索最基本的方法,从最常见的用例到更专业的用例。
1. 从列表或数组字典创建 DataFrame
这可以说是创建 DataFrame 最常见和最直观的方法。您从一个 Python 字典开始,其中键将成为列名,值将是包含每列数据的列表(或 NumPy 数组或 Pandas Series)。
工作原理: Pandas 将每个字典键映射到列标题,并将每个值列表映射到该列的行。这里的关键要求是所有列表的长度必须相同,因为每个列表代表一整列数据。
示例:
让我们创建一个包含全球不同城市信息的 DataFrame。
# 数据按列组织
city_data = {
'City': ['Tokyo', 'Delhi', 'Shanghai', 'São Paulo', 'Mumbai'],
'Country': ['Japan', 'India', 'China', 'Brazil', 'India'],
'Population_Millions': [37.3, 32.0, 28.5, 22.4, 20.9],
'Is_Coastal': [True, False, True, False, True]
}
# 创建 DataFrame
df_from_dict = pd.DataFrame(city_data)
print(df_from_dict)
输出:
City Country Population_Millions Is_Coastal
0 Tokyo Japan 37.3 True
1 Delhi India 32.0 False
2 Shanghai China 28.5 True
3 São Paulo Brazil 22.4 False
4 Mumbai India 20.9 True
关键要点: 当您的数据自然地按特征或类别组织时,此方法非常适用。它简洁、可读,并直接将字典结构转换为表格格式。
2. 从字典列表创建 DataFrame
另一种同样强大的方法是使用一个列表,其中每个元素都是一个字典。在这种结构中,每个字典代表一行,其键代表该行数据的列名。
工作原理: Pandas 遍历列表。对于每个字典,它会创建一个新行。字典键用于确定列。此方法非常灵活,因为如果字典缺少某个键,Pandas 会自动用 NaN(非数字)填充相应行中的该单元格,这是 Pandas 中缺失数据的标准标记。
示例:
让我们表示相同的城市数据,但这次将其结构化为记录列表。
# 数据按行(记录)组织
records_data = [
{'City': 'Tokyo', 'Country': 'Japan', 'Population_Millions': 37.3, 'Is_Coastal': True},
{'City': 'Delhi', 'Country': 'India', 'Population_Millions': 32.0, 'Is_Coastal': False},
{'City': 'Shanghai', 'Country': 'China', 'Population_Millions': 28.5},
{'City': 'São Paulo', 'Country': 'Brazil', 'Population_Millions': 22.4, 'Is_Coastal': False},
{'City': 'Cairo', 'Country': 'Egypt', 'Timezone': 'EET'} # 注意结构差异
]
# 创建 DataFrame
df_from_list_of_dicts = pd.DataFrame(records_data)
print(df_from_list_of_dicts)
输出:
City Country Population_Millions Is_Coastal Timezone
0 Tokyo Japan 37.3 True NaN
1 Delhi India 32.0 False NaN
2 Shanghai China 28.5 NaN NaN
3 São Paulo Brazil 22.4 False NaN
4 Cairo Egypt NaN NaN EET
请注意 Pandas 如何优雅地处理了不一致性。上海的 'Is_Coastal' 值为 NaN,因为它在其字典中缺失。为开罗创建了一个新的 'Timezone' 列,所有其他城市的值为 NaN。这使其成为处理半结构化数据(例如来自 API 的 JSON 响应)的绝佳选择。
关键要点: 当您的数据以一系列记录或观测值的形式出现时,请使用此方法。它在处理缺失数据和记录结构变化方面非常健壮。
3. 从 NumPy 数组创建 DataFrame
对于从事科学计算、机器学习或任何涉及大量数值运算领域的人来说,数据通常来源于 NumPy 数组。Pandas 构建在 NumPy 之上,这使得两者之间的集成无缝且高效。
工作原理: 您将一个二维 NumPy 数组传递给 pd.DataFrame() 构造函数。默认情况下,Pandas 将创建基于整数的索引和列。但是,您可以使用 index 和 columns 参数提供有意义的标签(并且应该这样做)。
示例:
让我们从一个随机生成的 5x4 NumPy 数组创建一个 DataFrame,代表随时间变化的传感器读数。
# 创建一个包含随机数据的 5x4 NumPy 数组
data_np = np.random.rand(5, 4)
# 定义列和索引标签
columns = ['Sensor_A', 'Sensor_B', 'Sensor_C', 'Sensor_D']
index = pd.to_datetime(['2023-10-27 10:00', '2023-10-27 10:01', '2023-10-27 10:02', '2023-10-27 10:03', '2023-10-27 10:04'])
# 创建 DataFrame
df_from_numpy = pd.DataFrame(data=data_np, index=index, columns=columns)
print(df_from_numpy)
输出(您的随机数会有所不同):
Sensor_A Sensor_B Sensor_C Sensor_D
2023-10-27 10:00:00 0.123456 0.987654 0.555555 0.111111
2023-10-27 10:01:00 0.234567 0.876543 0.666666 0.222222
2023-10-27 10:02:00 0.345678 0.765432 0.777777 0.333333
2023-10-27 10:03:00 0.456789 0.654321 0.888888 0.444444
2023-10-27 10:04:00 0.567890 0.543210 0.999999 0.555555
在此示例中,我们还引入了一个强大的功能:为时间序列数据使用 DatetimeIndex,这在 Pandas 中解锁了大量的基于时间的分析功能。
关键要点: 这是从同质数值数据创建 DataFrame 最节省内存的方法。它是与 NumPy、Scikit-learn 或 TensorFlow 等库进行接口时的标准选择。
4. 从列表的列表创建 DataFrame
此方法在概念上与从 NumPy 数组创建类似,但使用标准的 Python 列表。这是一种将以嵌套列表格式存储的表格数据进行转换的直接方式。
工作原理: 您提供一个列表,其中每个内部列表代表一行数据。与 NumPy 数组一样,强烈建议通过 columns 参数指定列名以提高清晰度。
示例:
# 数据作为行列表
product_data = [
['P001', 'Laptop', 1200.00, 'Electronics'],
['P002', 'Mouse', 25.50, 'Electronics'],
['P003', 'Desk Chair', 150.75, 'Furniture'],
['P004', 'Keyboard', 75.00, 'Electronics']
]
# 定义列名
column_names = ['ProductID', 'ProductName', 'Price_USD', 'Category']
# 创建 DataFrame
df_from_list_of_lists = pd.DataFrame(product_data, columns=column_names)
print(df_from_list_of_lists)
输出:
ProductID ProductName Price_USD Category 0 P001 Laptop 1200.00 Electronics 1 P002 Mouse 25.50 Electronics 2 P003 Desk Chair 150.75 Furniture 3 P004 Keyboard 75.00 Electronics
关键要点: 当您的数据已经结构化为行列表时,例如从没有标题的文件格式读取数据时,这是一种简单有效的方法。
高级初始化:自定义您的 DataFrame
除了提供原始数据之外,pd.DataFrame() 构造函数还提供了几个参数,用于在创建 DataFrame 时就控制其结构和属性。
指定索引
我们已经看到了 `index` 参数的实际应用。索引是 DataFrame 的一个重要组成部分,它为行提供标签,用于快速查找、数据对齐等。虽然 Pandas 提供了默认的数字索引(0, 1, 2, ...),但设置一个有意义的索引可以使您的数据更易于处理。
示例: 让我们重新使用我们的列表字典示例,但在创建时将 `City` 列设置为索引。
city_data = {
'Country': ['Japan', 'India', 'China', 'Brazil', 'India'],
'Population_Millions': [37.3, 32.0, 28.5, 22.4, 20.9],
'Is_Coastal': [True, False, True, False, True]
}
city_names = ['Tokyo', 'Delhi', 'Shanghai', 'São Paulo', 'Mumbai']
# 创建带有自定义索引的 DataFrame
df_with_index = pd.DataFrame(city_data, index=city_names)
print(df_with_index)
输出:
Country Population_Millions Is_Coastal
Tokyo Japan 37.3 True
Delhi India 32.0 False
Shanghai China 28.5 True
São Paulo Brazil 22.4 False
Mumbai India 20.9 True
现在,您可以使用这些有意义的标签访问行数据,例如使用 df_with_index.loc['Tokyo']。
控制数据类型(`dtype`)
Pandas 在推断数据类型方面做得很好(例如,识别数字、文本和布尔值)。但是,有时您需要为列强制指定特定的数据类型,以确保内存效率或启用特定操作。`dtype` 参数为您提供了这种控制。
示例: 假设我们有看起来像数字但应被视为文本(字符串)的产品 ID。
data = {
'ProductID': [101, 102, 103],
'Stock': [50, 75, 0]
}
# 创建 DataFrame 时为 'ProductID' 指定 dtype
df_types = pd.DataFrame(data, dtype={'ProductID': str, 'Stock': 'int32'})
print(df_types.dtypes)
输出:
ProductID object Stock int32 dtype: object
请注意,Pandas 中的 `str` 表示为 `object`。通过显式设置 `dtype`,我们防止 Pandas 将 `ProductID` 视为数字,这可能导致后续错误的计算或排序问题。使用更具体的整数类型(如 `int32` 而不是默认的 `int64`)也可以为大型数据集节省大量内存。
实际场景和最佳实践
选择正确的创建方法取决于您数据的原始格式。这是一个简单的决策指南:
- 您的数据是否按列组织(例如,每个特征一个列表)? 使用列表字典。这是一种自然的选择。
- 您的数据是否为一系列记录(例如,来自 JSON API)? 使用字典列表。它擅长处理记录中缺失或多余的字段。
- 您的数据是否为网格状数值数据(例如,来自科学计算)? 使用NumPy 数组。这是此用例性能最佳的选项。
- 您的数据是否为没有标题的简单逐行表格格式? 使用列表的列表并单独提供列名。
要避免的常见陷阱
- 列表字典中长度不相等: 这是一个常见错误。当从列表字典创建 DataFrame 时,每个列表必须具有完全相同的元素数量。否则,Pandas 将引发 `ValueError`。在创建之前,请务必确保您的列数据长度相等。
- 忽略索引: 在许多情况下,依赖默认的从 0 开始的索引是没问题的,但如果您的数据具有自然标识符(如产品 ID、用户 ID 或特定时间戳),从一开始就将其设置为索引可以简化您后续的代码。
- 忘记数据类型: 让 Pandas 推断类型在大多数情况下是有效的,但对于大型数据集或混合类型的列,性能可能会下降。对于需要被视为类别、字符串或特定数值类型的列,请主动设置 `dtype`,以节省内存并防止错误。
超越初始化:从文件创建 DataFrame
虽然本指南侧重于从内存中的 Python 对象创建 DataFrame,但了解在大多数实际场景中,您的数据将来自外部文件至关重要。Pandas 为此目的提供了一套高度优化的读取函数,包括:
pd.read_csv():用于逗号分隔值文件,是数据导入的主力。pd.read_excel():用于从 Microsoft Excel 电子表格读取数据。pd.read_json():用于从 JSON 文件或字符串读取数据。pd.read_sql():用于将数据库查询结果直接读取到 DataFrame 中。pd.read_parquet():用于从高效的、面向列的 Parquet 文件格式读取。
这些函数是您 Pandas 之旅的下一个逻辑步骤。掌握它们将使您能够将来自几乎任何来源的数据摄取到强大的 DataFrame 结构中。
结论:您数据掌握的基础
Pandas DataFrame 是 Python 中任何严肃数据工作的核心数据结构。正如我们所见,Pandas 提供了一套灵活直观的工具,可以从各种格式初始化这些结构。通过了解如何从字典、列表和 NumPy 数组创建 DataFrame,您已经为您的数据分析项目打下了坚实的基础。
关键在于选择最符合数据原始结构的方法。这不仅使您的代码更简洁、更具可读性,而且更高效。从这里开始,您就可以继续进行数据清洗、探索、转换和可视化等令人兴奋的任务。编程愉快!